package vip.xiaonuo.smzq.core.gson;

import com.aliyun.teautil.MapTypeAdapter;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import springfox.documentation.spring.web.json.Json;

import java.lang.reflect.Type;
import java.sql.Date;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class GsonUtil {

    private static Gson gson = null;

    static {
        if (gson == null) {// gson = new Gson();
            gson = new GsonBuilder().serializeNulls()//序列化输出值为null
                    //.setDateFormat("yyyy-MM-dd HH:mm:ss")//24 小时
                    .registerTypeAdapter(new TypeToken<Map<String, Object>>() {}.getType(), new MapTypeAdapter())
                    .registerTypeAdapter(new TypeToken<Object>() {}.getType(), new ObjectTypeAdapter())
                    //特殊类型注册
                    .registerTypeAdapter(LocalDateTime.class,new LocalDateTimeAdapter())
                    .registerTypeAdapter(Date.class,new DateAdapter())
                    .registerTypeAdapter(Timestamp.class,new TimestampTypeAdapter())
                    .registerTypeAdapterFactory(new NullStringToEmptyAdapterFactory<>())
                    //解决 空字符串转int JsonSyntaxException: java.lang.NumberFormatException: empty String
                    .registerTypeAdapter(int.class, new IntTypeAdapter())
                    .registerTypeAdapter(Integer.class, new IntTypeAdapter())
                    .registerTypeAdapter(Long.class, new LongTypeAdapter())
                    .registerTypeAdapter(long.class, new LongTypeAdapter())
                    .registerTypeAdapter(Double.class, new DoubleTypeAdapter())
                    .registerTypeAdapter(double.class, new DoubleTypeAdapter())
                    // swagger 兼容 gson
                    .registerTypeAdapter(Json.class, new SpringfoxJsonToGsonAdapter())
                    //避免Gson使用时将一些字符自动转换为Unicode转义字符  disableHtmlEscaping
                    .disableHtmlEscaping()
                    .create();
        }
    }



    private GsonUtil() {
    }

    /**
     * 转成json
     *
     * @param object
     * @return
     */
    public static String GsonString(Object object) {
        String gsonString = null;
        if (gson != null) {
            gsonString = gson.toJson(object);
        }
        return gsonString;
    }

    /**
     * 转成bean
     *
     * @param gsonString
     * @param cls
     * @return
     */
    public static <T> T GsonToBean(String gsonString, Class<T> cls) {
        T t = null;
        if (gson != null) {
            t = gson.fromJson(gsonString, cls);
        }
        return t;
    }

    /**
     * object 转成 entity
     * @param object
     * @param cls
     * @return T
     * @Date 2020/5/12 11:46
     * @auther eomer
     */
    public static <T> T ObjectToEntity(Object object, Class<T> cls) {
        return GsonToBean(GsonString(object),cls);
    }

    /**
     * 转成list
     *
     * @param gsonString
     * @param cls
     * @return
     */
    public static <T> List<T> GsonToList(String gsonString, Class<T> cls) {
        List<T> list = null;
        if (gson != null) {
            Type type = new ParameterizedTypeImpl(cls);
            list = gson.fromJson(gsonString, type);
        }
        return list;
    }

    /**
     * 转成list
     *
     * @param object
     * @param cls
     * @return
     */
    public static <T> List<T> ObjectToList(Object object, Class<T> cls) {
        return GsonToList(GsonString(object), cls);
    }

    /**
     * 转成list中有map的
     *
     * @param gsonString
     * @return
     */
    public static <T> List<Map<String, T>> GsonToListMaps(String gsonString) {
        List<Map<String, T>> list = null;
        if (gson != null) {
            list = gson.fromJson(gsonString,
                    new TypeToken<List<Map<String, T>>>() {
                    }.getType());
        }
        return list;
    }

    /**
     * 转成map的
     *
     * @param gsonString
     * @return
     */
    public static <T> Map<String, T> GsonToMaps(String gsonString) {
        Map<String, T> map = null;
        if (gson != null) {
//            map = gson.fromJson(gsonString, new TypeToken<Map<String, T>>() {}.getType());
            map = gson.fromJson(gsonString, new TypeToken<Map<String, Object>>() {}.getType());
        }
        return map;
    }

    /**
     * json字符串，转  Map<String, List<String>>
     * @param gsonString
     * @return java.util.Map<java.lang.String,java.util.List<java.lang.String>>
     * @Date 21/10/12 10:59
     * @auther eomer
     */
    public static Map<String, List<String>> GsonToMapString(String gsonString) {
        Map<String, List<String>> map = null;
        if (gson != null) {
            Map<String,Object> gsonMap = gson.fromJson(gsonString, new TypeToken<Map<String, Object>>() {}.getType());
            if(gsonMap!=null){
                map = new HashMap<>();
                for (Map.Entry<String, Object> ent : gsonMap.entrySet()) {
                    if(ent.getValue() instanceof List){
                        map.put(ent.getKey(),((List) ent.getValue()));
                    }else{
                        map.put(ent.getKey(), Arrays.asList(new String[]{ent.getValue()==null?null:ent.getValue().toString()}));
                    }
                }
            }
        }
        return map;
    }
}
